home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
dkbuts.zip
/
SA2DKB.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-05-16
|
11KB
|
374 lines
/*****************************************************************************
*
* sa2dkb.c
*
* from DKBTrace (c) 1990 David Buck
*
* This program reads a Sculpt-Animate 3D format scene file and generates an
* output file that may be read in to DKBTrace.
*
*
* This software is freely distributable. The source and/or object code may be
* copied or uploaded to communications services so long as this notice remains
* at the top of each file. If any changes are made to the program, you must
* clearly indicate in the documentation and in the programs startup message
* who it was who made the changes. The documentation should also describe what
* those changes were. This software may not be included in whole or in
* part into any commercial package without the express written consent of the
* author. It may, however, be included in other public domain or freely
* distributed software so long as the proper credit for the software is given.
*
* This software is provided as is without any guarantees or warranty. Although
* the author has attempted to find and correct any bugs in the software, he
* is not responsible for any damage caused by the use of the software. The
* author is under no obligation to provide service, corrections, or upgrades
* to this package.
*
* Despite all the legal stuff above, if you do find bugs, I would like to hear
* about them. Also, if you have any comments or questions, you may contact me
* at the following address:
*
* David Buck
* 22C Sonnet Cres.
* Nepean Ontario
* Canada, K2H 8W7
*
* I can also be reached on the following bulleton boards:
*
* OMX (613) 731-3419
* Mystic (613) 596-4249 or (613) 596-4772
*
* Fidonet: 1:163/109.9
* Internet: dbuck@ccs.carleton.ca
* The "You Can Call Me RAY" BBS (708) 358-5611
*
* IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es:
*
* The "You Can Call Me RAY" BBS (708) 358-5611
* The Information Exchange BBS (708) 945-5575
*
*****************************************************************************/
#include <stdio.h>
#include <stdlib.h> /* contains "malloc" and "exit" prototypes */
#include <string.h>
#define DBL double
typedef struct {
unsigned short Red, Green, Blue, Alpha;
} IMAGE_COLOUR;
IMAGE_COLOUR *iff_colour_map;
int colourmap_size;
FILE *f, *out, *out2, *texture_file;
struct Chunk_Header_Struct {
long name;
long size;
};
typedef struct Chunk_Header_Struct CHUNK_HEADER;
static CHUNK_HEADER Chunk_Header;
/* function prototypes */
/* char *malloc(unsigned int size); (defined in stdlib.h) */
void read_iff_file(void);
void close_all(void);
void add_texture(unsigned int, unsigned int, unsigned int, unsigned int);
void iff_error (void);
int read_byte (FILE *);
int read_word (FILE *);
long read_long (FILE *);
void Read_Chunk_Header (FILE *, CHUNK_HEADER *);
DBL *vertices_x, *vertices_y, *vertices_z;
DBL max_x, max_y, max_z, min_x, min_y, min_z;
#define FABS(x) ((x<0.0)?-x:x)
#define FORM 0x464f524dL
#define SC3D 0x53433344L
#define VERT 0x56455254L
#define FACE 0x46414345L
#define CMPNONE 0
char *Textures[7] = {"Dull", "Shiny", "Mirror", "Luminous", "Glass", "Metal", "Glass2"};
#define TEXTURE_TABLE_SIZE 16300
unsigned long *texture_table;
unsigned int texture_table_size = 0;
char outfile[80];
void close_all()
{
if (out != NULL) {
fclose (out);
unlink ("triangle.tmp");
}
if (out2 != NULL) {
fclose (out2);
unlink (outfile);
}
if (texture_file != NULL) {
fclose (texture_file);
unlink ("textures.tmp");
}
if (f != NULL) {
fclose (f);
}
}
void add_texture (texture, red, green, blue)
unsigned int texture, red, green, blue;
{
unsigned long texture_id;
int i;
texture_id = ((unsigned long)texture << 24) | ((unsigned long)red << 16) | (green << 8) | blue;
for (i = 0; (unsigned) i < texture_table_size; i++)
if (texture_id == texture_table[i])
return;
texture_table[texture_table_size++] = texture_id;
if (texture_table_size >= TEXTURE_TABLE_SIZE) {
fprintf (stderr, "Colour table overflow\n");
close_all();
exit(1);
}
fprintf (texture_file, "DECLARE %s_%d_%d_%d = TEXTURE %s COLOUR RED %f GREEN %f BLUE %f END_TEXTURE\n",
Textures[texture], red, green, blue,
Textures[texture], red/255.0, green/255.0, blue/255.0);
}
void iff_error ()
{
fprintf (stderr, "Invalid iff file\n");
close_all();
exit(1);
}
int read_byte(f)
FILE *f;
{
int c;
if ((c = getc(f)) == EOF)
iff_error();
return (c);
}
int read_word(f)
FILE *f;
{
int result;
result = read_byte(f)*256;
result += read_byte(f);
return (result);
}
long read_long(f)
FILE *f;
{
int i;
long result;
result = 0;
for (i = 0 ; i < 4 ; i++)
result = result * 256 + read_byte(f);
return (result);
}
void Read_Chunk_Header (f, dest)
FILE *f;
CHUNK_HEADER *dest;
{
dest->name = read_long(f);
dest->size = (int) read_long(f);
}
void read_iff_file()
{
int i;
int vert1, vert2, vert3;
unsigned int texture;
unsigned int red_int, green_int, blue_int;
max_x = max_y = max_z = -10000000.0;
min_x = min_y = min_z = 10000000.0;
while (1) {
Read_Chunk_Header(f, &Chunk_Header);
switch ((int) Chunk_Header.name) {
case FORM: if (read_long(f) != SC3D)
iff_error();
break;
case VERT:
if ((vertices_x = (DBL *)
malloc ((unsigned)Chunk_Header.size * (sizeof(DBL)/sizeof(long)))) == NULL) {
fprintf (stderr, "Cannot allocate memory for vertices_x array\n");
close_all();
exit(1);
}
if ((vertices_y = (DBL *)
malloc ((unsigned)Chunk_Header.size * (sizeof(DBL)/sizeof(long)))) == NULL) {
fprintf (stderr, "Cannot allocate memory for vertices_y array\n");
close_all();
exit(1);
}
if ((vertices_z = (DBL *)
malloc ((unsigned)Chunk_Header.size * (sizeof(DBL)/sizeof(long)))) == NULL) {
fprintf (stderr, "Cannot allocate memory for vertices_z array\n");
close_all();
exit(1);
}
for (i = 0 ; (long) i < Chunk_Header.size/12L ; i++) {
vertices_x[i] = read_long(f) / 10000.0;
if (vertices_x[i] < min_x)
min_x = vertices_x[i];
if (vertices_x[i] > max_x)
max_x = vertices_x[i];
vertices_y[i] = read_long(f) / 10000.0;
if (vertices_y[i] < min_y)
min_y = vertices_y[i];
if (vertices_y[i] > max_y)
max_y = vertices_y[i];
vertices_z[i] = read_long(f) / 10000.0;
if (vertices_z[i] < min_z)
min_z = vertices_z[i];
if (vertices_z[i] > max_z)
max_z = vertices_z[i];
}
break;
case FACE: for (i = 0 ; (long) i < Chunk_Header.size/16L ; i++) {
vert1 = (int) read_long(f);
vert2 = (int) read_long(f);
vert3 = (int) read_long(f);
red_int = read_byte(f);
green_int = read_byte(f);
blue_int = read_byte(f);
texture = read_byte(f);
texture &= 0x07; /* mask upper bits */
add_texture (texture, red_int, green_int, blue_int);
fprintf (out, "TRIANGLE <%f %f %f> <%f %f %f> <%f %f %f> TEXTURE %s_%d_%d_%d END_TEXTURE END_TRIANGLE\n",
vertices_x[vert1], vertices_y[vert1], vertices_z[vert1],
vertices_x[vert2], vertices_y[vert2], vertices_z[vert2],
vertices_x[vert3], vertices_y[vert3], vertices_z[vert3],
Textures[texture], red_int, green_int, blue_int);
}
return;
default:
for (i = 0 ; (long) i < Chunk_Header.size ; i++)
if (getc(f) == EOF)
iff_error();
break;
}
}
}
void main (argc, argv)
int argc;
char **argv;
{
int c;
if (argc != 3) {
fprintf (stderr, "Usage: %s <scene-file> <output-file>\n", argv[0]);
exit (1);
}
f = out = out2 = texture_file = NULL;
strcpy(outfile, argv[2]);
if ((texture_table = (unsigned long *) malloc((unsigned int)TEXTURE_TABLE_SIZE * sizeof (unsigned long))) == NULL) {
fprintf (stderr, "Cannot allocate memory for texture table\n");
exit(1);
}
if ((f = fopen(argv[1], "rb")) == NULL) {
fprintf (stderr, "Cannot open IFF file %s\n", argv[1]);
exit(1);
}
if ((out = fopen("triangle.tmp", "w")) == NULL) {
fprintf (stderr, "Cannot open temporary file triangle.tmp\n");
close_all();
exit(1);
}
if ((texture_file = fopen("textures.tmp", "w")) == NULL) {
fprintf (stderr, "Cannot open temporary file textures.tmp\n");
close_all();
exit(1);
}
fprintf(out, "\nOBJECT\n UNION\n");
read_iff_file();
fprintf(out, " END_UNION\n");
fprintf(out, " BOUNDED_BY\n INTERSECTION\n");
fprintf(out, " PLANE <1.0 0.0 0.0> %1.02f END_PLANE\n", FABS(max_x) * 1.01);
fprintf(out, " PLANE <-1.0 0.0 0.0> %1.02f END_PLANE\n", FABS(min_x) * 1.01);
fprintf(out, " PLANE <0.0 1.0 0.0> %1.02f END_PLANE\n", FABS(max_y) * 1.01);
fprintf(out, " PLANE <0.0 -1.0 0.0> %1.02f END_PLANE\n", FABS(min_y) * 1.01);
fprintf(out, " PLANE <0.0 0.0 1.0> %1.02f END_PLANE\n", FABS(max_z) * 1.01);
fprintf(out, " PLANE <0.0 0.0 -1.0> %1.02f END_PLANE\n", FABS(min_z) * 1.01);
fprintf(out, " END_INTERSECTION\n END_BOUND\n \nEND_OBJECT\n");
printf ("X values range from %f to %f\n", min_x, max_x);
printf ("Y values range from %f to %f\n", min_y, max_y);
printf ("Z values range from %f to %f\n", min_z, max_z);
fclose(f);
fflush(out);
fclose(out);
fflush(texture_file);
fclose(texture_file);
if ((out2 = fopen (argv[2], "w")) == NULL) {
fprintf (stderr, "Cannot open output file %s\n", argv[2]);
exit(1);
}
if ((out = fopen("triangle.tmp", "r")) == NULL) {
fprintf (stderr, "Cannot open temporary file triangle.tmp\n");
close_all();
exit(1);
}
if ((texture_file = fopen("textures.tmp", "r")) == NULL) {
fprintf (stderr, "Cannot open temporary file textures.tmp\n");
close_all();
exit(1);
}
while ((c = getc(texture_file)) != EOF)
putc (c, out2);
while ((c = getc(out)) != EOF)
putc (c, out2);
fflush(out2);
fclose(out2);
out2 = NULL; /* make sure close_all doesn't delete out2 file */
close_all();
exit(0);
}